﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;

namespace Crucible.Models
{

    public enum NodeType
    {
        Assertion = 1,
        Interpretation = 2,
        Source = 3,
        Originator = 4
    }

    [DataContract]
    public class Node
    {
        
        public Node()
        {
            Type = NodeType.Assertion;
        }

        [DataMember(IsRequired = true)]
        public int Id { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        public string Title { get; set; }

        [DataMember(IsRequired = true)]
        public Node Replacement { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        public bool Published { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        public int AddedBy_UserId { get; set; }

        [DataMember(IsRequired = true)]
        [ForeignKey("AddedBy_UserId")]
        public virtual UserProfile AddedBy { get; set; }

        //public Attribution Attribution { get; set; }
        [DataMember(IsRequired = true)]
        public DateTime DateAdded { get; set; }

        public List<Comment> Comments { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        public NodeType Type { get; set; }

        //public Source Source { get; set; }

        [DataMember(IsRequired = true)]
        [Url(ErrorMessage = "Invalid URL")]
        public string Link { get; set; }

        [DataMember(IsRequired = true)]
        public string Body { get; set; }

        [DataMember(IsRequired = true)]
        public string Attribution { get; set; }

        [DataMember(IsRequired = true)]
        public DateTime? DateOriginated { get; set; }

    }

    public class NodeLink
    {
        public int Id { get; set; }

        [Required]
        public int Parent_Id { get; set; }

        [Required]
        public int Child_Id { get; set; }

        [ForeignKey("Parent_Id")]
        public virtual Node Parent { get; set; }

        [ForeignKey("Child_Id")]
        public virtual Node Child { get; set; }
    }

    [DataContract]
    public class Comment
    {
        [DataMember(IsRequired = true)]
        public int Id { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        public int Author_UserId { get; set; }

        [ForeignKey("Author_UserId")]
        public virtual UserProfile Author { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        public string Body { get; set; }

        public int? Parent_Id { get; set; }

        [ForeignKey("Parent_Id")]
        public Comment Parent { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        public int Node_Id { get; set; }

        [ForeignKey("Node_Id")]
        public Node Node { get; set; }

        [DataMember(IsRequired = true)]
        public int Score { get; set; }

        [DataMember(IsRequired = true)]
        public DateTime DateAdded { get; set; }

        [DataMember(IsRequired = true)]
        public bool IsDeleted { get; set; }

    }

    [DataContract]
    public class NodeVote
    {

        [Key, Column(Order=1)]
        [Required]
        [DataMember(IsRequired = true)]
        public int Author_UserId { get; set; }

        [ForeignKey("Author_UserId")]
        public virtual UserProfile Author { get; set; }

        [Key, Column(Order=0)]
        [Required]
        [DataMember(IsRequired = true)]
        public int Node_Id { get; set; }

        [ForeignKey("Node_Id")]
        public virtual Node Node { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        [Range(-2, 2)]
        public int Agreement { get; set; }

        [Required]
        [DataMember(IsRequired = true)]
        [Range(-2, 2)]
        public int Logic { get; set; }

        public List<Objection> Objections { get; set; }

    }

    public class CommentVote
    {
        [Key, Column(Order = 0)]
        [Required]
        public int Comment_Id { get; set; }

        [ForeignKey("Comment_Id")]
        public virtual Comment Comment { get; set; }

        [Key, Column(Order = 1)]
        [Required]
        public int Voter_UserId { get; set; }

        [ForeignKey("Voter_UserId")]
        public virtual UserProfile Voter { get; set; }

        [Required]
        [Range(-1, 1)]
        public int Vote { get; set; }

    }

    public class Objection
    {
        public int Id { get; set; }

        public virtual Fallacy Fallacy { get; set; }

        public string Explanation { get; set; }
    }

    public class Fallacy
    {
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        [Required]
        public string Description { get; set; }

        [Url(ErrorMessage="Invalid fallacy URL")]
        [Required]
        public string Link { get; set; }
    }
}